﻿
Imports std
Imports storoomc

Public Class storoomCallbackManager
    Public MustInherit Class callbackParameter
        Public slice As storageInterface = Nothing
        Public operationResult As Boolean = False
    End Class

    Public Class capacityParameter
        Inherits callbackParameter
        Public cap As UInt64 = 0
    End Class

    Public Class closeParameter
        Inherits callbackParameter
    End Class

    Public Class deleteParameter
        Inherits callbackParameter
        Public key As String = Nothing
    End Class

    Public Class emptyParameter
        Inherits callbackParameter
    End Class

    Public Class fullParameter
        Inherits callbackParameter
    End Class

    Public Class keycountParameter
        Inherits callbackParameter
        Public count As UInt64 = 0
    End Class

    Public Class listParameter
        Inherits callbackParameter
        Public list As vector(Of String) = Nothing
    End Class

    Public Class openParameter
        Inherits callbackParameter
    End Class

    Public Class readParameter
        Inherits callbackParameter
        Public key As String = Nothing
        Public buff As bytes = Nothing
    End Class

    Public Class retireParameter
        Inherits callbackParameter
    End Class

    Public Class seekParameter
        Inherits callbackParameter
        Public key As String = Nothing
    End Class

    Public Class sizeofParameter
        Inherits callbackParameter
        Public key As String = Nothing
        Public size As UInt64 = 0
    End Class

    Public Class valuesizeParameter
        Inherits callbackParameter
        Public size As UInt64 = 0
    End Class

    Public Class writeParameter
        Inherits callbackParameter
        Public key As String = Nothing
        Public buff As bytes = Nothing
    End Class

    Private creator As resolver = Nothing
    Private cbs As vector(Of _do(Of callbackParameter, Boolean))() = Nothing

    Public Sub New()
        ReDim cbs(jobType.count - 1)
        For i As Int64 = 0 To jobType.count - 1
            cbs(i) = New vector(Of _do(Of callbackParameter, Boolean))()
        Next
        creator = New resolver()
        register(Of capacityParameter)(Function() As capacityParameter
                                           Return New capacityParameter()
                                       End Function)
        register(Of closeParameter)(Function() As closeParameter
                                        Return New closeParameter()
                                    End Function)
        register(Of deleteParameter)(Function() As deleteParameter
                                         Return New deleteParameter()
                                     End Function)
        register(Of emptyParameter)(Function() As emptyParameter
                                        Return New emptyParameter()
                                    End Function)
        register(Of fullParameter)(Function() As fullParameter
                                       Return New fullParameter()
                                   End Function)
        register(Of keycountParameter)(Function() As keycountParameter
                                           Return New keycountParameter()
                                       End Function)
        register(Of listParameter)(Function() As listParameter
                                       Return New listParameter()
                                   End Function)
        register(Of openParameter)(Function() As openParameter
                                       Return New openParameter()
                                   End Function)
        register(Of readParameter)(Function() As readParameter
                                       Return New readParameter()
                                   End Function)
        register(Of retireParameter)(Function() As retireParameter
                                         Return New retireParameter()
                                     End Function)
        register(Of seekParameter)(Function() As seekParameter
                                       Return New seekParameter()
                                   End Function)
        register(Of sizeofParameter)(Function() As sizeofParameter
                                         Return New sizeofParameter()
                                     End Function)
        register(Of valuesizeParameter)(Function() As valuesizeParameter
                                            Return New valuesizeParameter()
                                        End Function)
        register(Of writeParameter)(Function() As writeParameter
                                        Return New writeParameter()
                                    End Function)
        assert(creator.size() = jobType.count)
    End Sub

    Public Sub register(Of T As callbackParameter)(ByVal d As _do(Of T))
        creator.register(Of T)(d)
    End Sub

    Private Function resolve(Of T As callbackParameter)() As T
        Return creator.resolve(Of T)()
    End Function

    Private Function callback(Of CB As callbackParameter) _
                             (ByVal t As jobType,
                              ByRef p As CB,
                              ByVal initial As void(Of CB)) As Boolean
        If t < 0 OrElse t >= jobType.count Then
            Return False
        End If
        If cbs(t) Is Nothing OrElse cbs(t).size() = 0 Then
            Return True
        End If

        initial(p)
        assert(Not p Is Nothing)
        For i As Int64 = 0 To cbs(t).size() - 1
            assert(Not cbs(t)(i) Is Nothing)
            If Not cbs(t)(i)(p) Then
                Return False
            End If
        Next
        Return True
    End Function

    Private Function register(ByVal t As jobType, ByVal d As _do(Of callbackParameter, Boolean)) As Boolean
        If t < 0 OrElse t >= jobType.count Then
            Return False
        End If
        If d Is Nothing Then
            Return False
        End If

        Return cbs(t).push_back(d)
    End Function

    Private Function callback(Of T As callbackParameter) _
                             (ByVal slice As storageInterface, ByVal result As Boolean,
                              ByVal jobType As jobType,
                              ByRef p As T,
                              Optional ByVal initial As void(Of T) = Nothing) As Boolean
        Return callback(jobType, p, Sub(ByRef i As T)
                                        If i Is Nothing Then
                                            If creator.hasResolver(Of T)() Then
                                                i = creator.resolve(Of T)()
                                            Else
                                                i = alloc(Of T)()
                                            End If
                                            assert(Not i Is Nothing)
                                        End If
                                        i.slice = slice
                                        i.operationResult = result
                                        If Not initial Is Nothing Then
                                            initial(i)
                                        End If
                                    End Sub)
    End Function

    Public Function registerCapacity(ByVal d As _do(Of callbackParameter, Boolean)) As Boolean
        Return register(jobType.capacity, d)
    End Function

    Public Function capacity(ByVal slice As storageInterface, ByVal result As Boolean, ByVal cap As UInt64,
                             ByRef p As capacityParameter) As Boolean
        Return callback(slice, result, jobType.capacity, p, Sub(ByRef i As capacityParameter)
                                                                i.cap = cap
                                                            End Sub)
    End Function

    Public Function registerClose(ByVal d As _do(Of callbackParameter, Boolean)) As Boolean
        Return register(jobType.close, d)
    End Function

    Public Function close(ByVal slice As storageInterface, ByVal result As Boolean,
                          ByRef p As closeParameter) As Boolean
        Return callback(slice, result, jobType.close, p)
    End Function

    Public Function registerDelete(ByVal d As _do(Of callbackParameter, Boolean)) As Boolean
        Return register(jobType.delete, d)
    End Function

    Public Function delete(ByVal slice As storageInterface, ByVal key As String, ByVal result As Boolean,
                           ByRef p As deleteParameter) As Boolean
        Return callback(slice, result, jobType.delete, p, Sub(ByRef i As deleteParameter)
                                                              i.key = key
                                                          End Sub)
    End Function

    Public Function registerEmpty(ByVal d As _do(Of callbackParameter, Boolean)) As Boolean
        Return register(jobType.empty, d)
    End Function

    Public Function empty(ByVal slice As storageInterface, ByVal result As Boolean,
                          ByRef p As emptyParameter) As Boolean
        Return callback(slice, result, jobType.empty, p)
    End Function

    Public Function registerFull(ByVal d As _do(Of callbackParameter, Boolean)) As Boolean
        Return register(jobType.full, d)
    End Function

    Public Function full(ByVal slice As storageInterface, ByVal result As Boolean,
                         ByRef p As fullParameter) As Boolean
        Return callback(slice, result, jobType.full, p)
    End Function

    Public Function registerKeycount(ByVal d As _do(Of callbackParameter, Boolean)) As Boolean
        Return register(jobType.keycount, d)
    End Function

    Public Function keycount(ByVal slice As storageInterface, ByVal result As Boolean, ByVal count As UInt64,
                             ByRef p As keycountParameter) As Boolean
        Return callback(slice, result, jobType.keycount, p, Sub(ByRef i As keycountParameter)
                                                                i.count = count
                                                            End Sub)
    End Function

    Public Function registerList(ByVal d As _do(Of callbackParameter, Boolean)) As Boolean
        Return register(jobType.list, d)
    End Function

    Public Function list(ByVal slice As storageInterface,
                         ByVal result As Boolean,
                         ByVal l As vector(Of String),
                         ByRef p As listParameter) As Boolean
        Return callback(slice, result, jobType.list, p, Sub(ByRef i As listParameter)
                                                            i.list = l
                                                        End Sub)
    End Function

    Public Function registerOpen(ByVal d As _do(Of callbackParameter, Boolean)) As Boolean
        Return register(jobType.open, d)
    End Function

    Public Function open(ByVal slice As storageInterface, ByVal result As Boolean,
                         ByRef p As openParameter) As Boolean
        Return callback(slice, result, jobType.open, p)
    End Function

    Public Function registerRead(ByVal d As _do(Of callbackParameter, Boolean)) As Boolean
        Return register(jobType.read, d)
    End Function

    Public Function read(ByVal slice As storageInterface,
                         ByVal result As Boolean,
                         ByVal key As String,
                         ByVal buff As bytes,
                         ByRef p As readParameter) As Boolean
        Return callback(slice, result, jobType.read, p, Sub(ByRef i As readParameter)
                                                            i.key = key
                                                            i.buff = buff
                                                        End Sub)
    End Function

    Public Function registerRetire(ByVal d As _do(Of callbackParameter, Boolean)) As Boolean
        Return register(jobType.retire, d)
    End Function

    Public Function retire(ByVal slice As storageInterface, ByVal result As Boolean,
                           ByRef p As retireParameter) As Boolean
        Return callback(slice, result, jobType.retire, p)
    End Function

    Public Function registerSeek(ByVal d As _do(Of callbackParameter, Boolean)) As Boolean
        Return register(jobType.seek, d)
    End Function

    Public Function seek(ByVal slice As storageInterface, ByVal result As Boolean, ByVal key As String,
                         ByRef p As seekParameter) As Boolean
        Return callback(slice, result, jobType.seek, p, Sub(ByRef i As seekParameter)
                                                            i.key = key
                                                        End Sub)
    End Function

    Public Function registerSizeof(ByVal d As _do(Of callbackParameter, Boolean)) As Boolean
        Return register(jobType.sizeof, d)
    End Function

    Public Function sizeof(ByVal slice As storageInterface,
                           ByVal result As Boolean,
                           ByVal key As String,
                           ByVal size As UInt64,
                           ByRef p As sizeofParameter) As Boolean
        Return callback(slice, result, jobType.sizeof, p, Sub(ByRef i As sizeofParameter)
                                                              i.key = key
                                                              i.size = size
                                                          End Sub)
    End Function

    Public Function registerValuesize(ByVal d As _do(Of callbackParameter, Boolean)) As Boolean
        Return register(jobType.valuesize, d)
    End Function

    Public Function valuesize(ByVal slice As storageInterface, ByVal result As Boolean, ByVal size As UInt64,
                              ByRef p As valuesizeParameter) As Boolean
        Return callback(slice, result, jobType.valuesize, p, Sub(ByRef i As valuesizeParameter)
                                                                 i.size = size
                                                             End Sub)
    End Function

    Public Function registerWrite(ByVal d As _do(Of callbackParameter, Boolean)) As Boolean
        Return register(jobType.write, d)
    End Function

    Public Function write(ByVal slice As storageInterface,
                          ByVal result As Boolean,
                          ByVal key As String,
                          ByVal buff As bytes,
                          ByRef p As writeParameter) As Boolean
        Return callback(slice, result, jobType.write, p, Sub(ByRef i As writeParameter)
                                                             i.key = key
                                                             i.buff = buff
                                                         End Sub)
    End Function
End Class
